using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Networking;

[RequireComponent(typeof(CarControl))]
public class Vehicle : DamageManager
{
	public bool NeedParachute;

	public Seat[] Seats;

	public string VehicleName;

	[SyncVar]
	public string VehicleID;

	[HideInInspector]
	public bool incontrol;

	[SyncVar(hook = "OnSeatDataChanged")]
	public string SeatsData;

	[SyncVar]
	private Vector3 positionSync;

	[SyncVar]
	private Quaternion rotationSync;

	public bool hasDriver;

	public string NetworkVehicleID
	{
		get
		{
			return VehicleID;
		}
		[param: In]
		set
		{
			SetSyncVar(value, ref VehicleID, 64u);
		}
	}

	public string NetworkSeatsData
	{
		get
		{
			return SeatsData;
		}
		[param: In]
		set
		{
			ref string seatsData = ref SeatsData;
			if (NetworkServer.localClientActive && !base.syncVarHookGuard)
			{
				base.syncVarHookGuard = true;
				OnSeatDataChanged(value);
				base.syncVarHookGuard = false;
			}
			SetSyncVar(value, ref seatsData, 128u);
		}
	}

	public Vector3 NetworkpositionSync
	{
		get
		{
			return positionSync;
		}
		[param: In]
		set
		{
			SetSyncVar(value, ref positionSync, 256u);
		}
	}

	public Quaternion NetworkrotationSync
	{
		get
		{
			return rotationSync;
		}
		[param: In]
		set
		{
			SetSyncVar(value, ref rotationSync, 512u);
		}
	}

	public override void Awake()
	{
		if (Seats.Length <= 0)
		{
			Seats = (Seat[])GetComponentsInChildren(typeof(Seat));
		}
		base.Awake();
	}

	public override void OnDestroyed()
	{
		for (int i = 0; i < Seats.Length; i++)
		{
			Seats[i].CleanSeat();
		}
		base.OnDestroyed();
	}

	public override void OnStartClient()
	{
		if (base.isServer)
		{
			NetworkVehicleID = base.netId.ToString();
		}
		OnSeatDataChanged(SeatsData);
		base.OnStartClient();
	}

	private void OnSeatDataChanged(string seatsdata)
	{
		NetworkSeatsData = seatsdata;
		string[] array = seatsdata.Split(","[0]);
		if (array.Length >= Seats.Length)
		{
			for (int i = 0; i < Seats.Length; i++)
			{
				Seats[i].PassengerID = array[i];
			}
		}
	}

	private void GenSeatsData()
	{
		string text = string.Empty;
		for (int i = 0; i < Seats.Length; i++)
		{
			text = ((!(Seats[i].PassengerID != "none")) ? (text + "none,") : (text + Seats[i].PassengerID + ","));
		}
		NetworkSeatsData = text;
	}

	public void EjectAllSeat()
	{
		for (int i = 0; i < Seats.Length; i++)
		{
			if (Seats[i].passenger != null)
			{
				Seats[i].passenger.OutVehicle();
			}
		}
	}

	private GameObject findPlayerByID(string userID)
	{
		TargetCollector targetCollector = UnitZ.aiManager.FindTargetTag("Player");
		GameObject[] targets = targetCollector.Targets;
		for (int i = 0; i < targets.Length; i++)
		{
			if (targets[i] != null)
			{
				CharacterSystem component = targets[i].GetComponent<CharacterSystem>();
				if (component != null && component.UserID == userID)
				{
					return targets[i];
				}
			}
		}
		return null;
	}

	private void UpdatePassengerOnSeats()
	{
		hasDriver = false;
		for (int i = 0; i < Seats.Length; i++)
		{
			if (Seats[i].PassengerID != "none")
			{
				GameObject gameObject = findPlayerByID(Seats[i].PassengerID);
				if (!gameObject)
				{
					continue;
				}
				CharacterDriver component = gameObject.GetComponent<CharacterDriver>();
				if (!component)
				{
					continue;
				}
				component.NeedParachute = NeedParachute;
				FPSController component2 = component.GetComponent<FPSController>();
				if ((bool)component2)
				{
					component2.FixedRotation();
				}
				if (Seats[i].ForceView != PlayerViewType.None)
				{
					PlayerView component3 = component.GetComponent<PlayerView>();
					if ((bool)component3)
					{
						component3.View = Seats[i].ForceView;
						component3.OrbitDistance = Seats[i].ViewDistance;
					}
				}
				if (Seats[i].FixRotation)
				{
					component.transform.rotation = Seats[i].transform.rotation;
				}
				component.character.Motor.grounded = false;
				component.transform.position = Seats[i].transform.position;
				component.transform.parent = Seats[i].transform;
				component.CurrentVehicle = this;
				component.character.controller.enabled = false;
				component.DrivingSeat = Seats[i];
				hasDriver = true;
				if (!component.character.IsAlive)
				{
					Seats[i].PassengerID = "none";
				}
			}
			else
			{
				Seats[i].CleanSeat();
			}
		}
		if (base.isServer)
		{
			GenSeatsData();
		}
	}

	public void GetOutTheVehicle(CharacterDriver driver)
	{
		int num = 0;
		while (true)
		{
			if (num < Seats.Length)
			{
				if (Seats[num].PassengerID == driver.character.UserID)
				{
					break;
				}
				num++;
				continue;
			}
			return;
		}
		Seats[num].PassengerID = "none";
	}

	public virtual void Pickup(GameObject character)
	{
		character.SendMessage("PickupCarCallback", this);
	}

	public void GetInTheVehicle(CharacterDriver driver, int seatID)
	{
		if ((bool)driver && seatID != -1 && seatID >= 0 && seatID < Seats.Length)
		{
			driver.CurrentVehicle = this;
			Seats[seatID].PassengerID = driver.character.UserID;
			Seats[seatID].passenger = driver;
		}
	}

	public int FindOpenSeatID()
	{
		for (int i = 0; i < Seats.Length; i++)
		{
			if (Seats[i].PassengerID == "none")
			{
				return i;
			}
		}
		return -1;
	}

	public virtual void Drive(Vector2 input, bool brake)
	{
	}

	public override void Update()
	{
		UpdateFunction();
		UpdateDriver();
		base.Update();
	}

	public void UpdateFunction()
	{
		UpdatePassengerOnSeats();
		if (base.isServer)
		{
			NetworkpositionSync = base.transform.position;
			NetworkrotationSync = base.transform.rotation;
		}
		base.transform.position = Vector3.Lerp(base.transform.position, positionSync, 0.5f);
		base.transform.rotation = Quaternion.Lerp(base.transform.rotation, rotationSync, 0.5f);
	}

	public void UpdateDriver()
	{
		for (int i = 0; i < Seats.Length; i++)
		{
			if (Seats[i].IsDriver && Seats[i].passenger != null)
			{
				return;
			}
		}
		incontrol = false;
	}

	public void GetInfo()
	{
		string info = "Get in\n" + VehicleName;
		UnitZ.Hud.ShowInfo(info, base.transform.position);
	}

	private void UNetVersion()
	{
	}

	public override bool OnSerialize(NetworkWriter writer, bool forceAll)
	{
		bool flag = base.OnSerialize(writer, forceAll);
		if (forceAll)
		{
			writer.Write(VehicleID);
			writer.Write(SeatsData);
			writer.Write(positionSync);
			writer.Write(rotationSync);
			return true;
		}
		bool flag2 = false;
		if ((base.syncVarDirtyBits & 0x40) != 0)
		{
			if (!flag2)
			{
				writer.WritePackedUInt32(base.syncVarDirtyBits);
				flag2 = true;
			}
			writer.Write(VehicleID);
		}
		if ((base.syncVarDirtyBits & 0x80) != 0)
		{
			if (!flag2)
			{
				writer.WritePackedUInt32(base.syncVarDirtyBits);
				flag2 = true;
			}
			writer.Write(SeatsData);
		}
		if ((base.syncVarDirtyBits & 0x100) != 0)
		{
			if (!flag2)
			{
				writer.WritePackedUInt32(base.syncVarDirtyBits);
				flag2 = true;
			}
			writer.Write(positionSync);
		}
		if ((base.syncVarDirtyBits & 0x200) != 0)
		{
			if (!flag2)
			{
				writer.WritePackedUInt32(base.syncVarDirtyBits);
				flag2 = true;
			}
			writer.Write(rotationSync);
		}
		if (!flag2)
		{
			writer.WritePackedUInt32(base.syncVarDirtyBits);
		}
		return flag2 | flag;
	}

	public override void OnDeserialize(NetworkReader reader, bool initialState)
	{
		base.OnDeserialize(reader, initialState);
		if (initialState)
		{
			VehicleID = reader.ReadString();
			SeatsData = reader.ReadString();
			positionSync = reader.ReadVector3();
			rotationSync = reader.ReadQuaternion();
			return;
		}
		int num = (int)reader.ReadPackedUInt32();
		if ((num & 0x40) != 0)
		{
			VehicleID = reader.ReadString();
		}
		if ((num & 0x80) != 0)
		{
			OnSeatDataChanged(reader.ReadString());
		}
		if ((num & 0x100) != 0)
		{
			positionSync = reader.ReadVector3();
		}
		if ((num & 0x200) != 0)
		{
			rotationSync = reader.ReadQuaternion();
		}
	}
}
